package com.example.myapplication1;


import android.os.Build;

import androidx.annotation.RequiresApi;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import Decoder.BASE64Encoder;

/**
 * Copyright (C), 2020, 重庆八进制有限公司
 *
 * @author: weng
 * @last-modifier: weng
 * @version: 1.0
 * @create-date: 2020/8/19 16:26
 * @last-modify-date: 2020/8/19 16:26
 * @description:
 */
public class Sender {

    /*
     * 计算MD5+BASE64
     */
    public static String MD5Base64(String s) {
        if (s == null)
            return null;
        String encodeStr = "";
        byte[] utfBytes = s.getBytes();
        MessageDigest mdTemp;
        try {
            mdTemp = MessageDigest.getInstance("MD5");
            mdTemp.update(utfBytes);
            byte[] md5Bytes = mdTemp.digest();
            BASE64Encoder b64Encoder = new BASE64Encoder();
            encodeStr = b64Encoder.encode(md5Bytes);
        } catch (Exception e) {
            throw new Error("Failed to generate MD5 : " + e.getMessage());
        }
        return encodeStr;
    }

    /*
     * 计算 HMAC-SHA1
     */
    public static String HMACSha1(String data, String key) {
        String result;
        try {
            SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
            Mac mac = Mac.getInstance("HmacSHA1");
            mac.init(signingKey);
            byte[] rawHmac = mac.doFinal(data.getBytes());
            result = (new BASE64Encoder()).encode(rawHmac);
        } catch (Exception e) {
            throw new Error("Failed to generate HMAC : " + e.getMessage());
        }
        return result;
    }

    /*
     * 获取时间
     */
    public static String toGMTString(Date date) {
        SimpleDateFormat df = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z", Locale.CHINA);
        df.setTimeZone(new java.util.SimpleTimeZone(0, "GMT"));
        return df.format(date);
    }


    @RequiresApi(api = Build.VERSION_CODES.O)
    public static String toGMTString( ) {

        String timeStr1= LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        DateTimeFormatter formatter0 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.systemDefault());
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'");

        ZonedDateTime zoneTime = ZonedDateTime.parse(timeStr1, formatter0);
        String youTimeStr = zoneTime.withFixedOffsetZone().format(formatter);
        return youTimeStr;
    }



    /*
     * 发送POST请求
     */

    /**
     * https://mt.cn-hangzhou.aliyuncs.com/?
     * AccessKeyId=TMP.3KdSxPsjYbSeNG2cBLWMBkZ9qnYTuZ7359JMvCP3DVtmsyRdQLfMRk2AVGkKXqi67GYQc5UPcEdt37uJn2fXqzZtQJ33FP
     * &Action=TranslateGeneral&
     * Format=JSON&FormatType=text&RegionId=cn-hangzhou&SecureTransport=true&SignatureMethod=HMAC-SHA1&SignatureNonce=b2b63eb82217de56b2444c37692d880b&SignatureVersion=1.0&
     * SourceIp=113.250.254.220&SourceLanguage=zh&SourceText=%E4%BD%A0%E5%A5%BD12342&TargetLanguage=en&
     * Timestamp=2020-08-17T06%3A28%3A52Z&Version=2018-10-12&Signature=kbWoQpDiFW%2BijIdyVK7Qk7MZvuA%3D
     */
    public static String sendPost(String url, String body, String ak_id, String ak_secret) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            /*
             * http header 参数
             */
            String method = "GET";
            String accept = "application/json";
            String content_type = "application/json;chrset=utf-8";
            String path = realUrl.getFile();
            String date = toGMTString(new Date());
            String host = realUrl.getHost();
            // 1.对body做MD5+BASE64加密
            String bodyMd5 = MD5Base64(body);
            String uuid = UUID.randomUUID().toString();
            String stringToSign = method + "\n" + accept + "\n" + bodyMd5 + "\n" + content_type + "\n" + date + "\n"
                    + "x-acs-signature-method:HMAC-SHA1\n"
                    + "x-acs-signature-nonce:" + uuid + "\n"
                    + "x-acs-version:2019-01-02\n"
                    + path;
            // 2.计算 HMAC-SHA1
            String signature = HMACSha1(stringToSign, ak_secret);
            // 3.得到 authorization header
            String authHeader = "acs " + ak_id + ":" + signature;
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("Accept", accept);
            conn.setRequestProperty("Content-Type", content_type);
            conn.setRequestProperty("Content-MD5", bodyMd5);
            conn.setRequestProperty("Date", date);
            conn.setRequestProperty("Host", host);
            conn.setRequestProperty("Authorization", authHeader);
            conn.setRequestProperty("x-acs-signature-nonce", uuid);
            conn.setRequestProperty("x-acs-signature-method", "HMAC-SHA1");
            conn.setRequestProperty("x-acs-version", "2019-01-02");  // 版本可选
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(body);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            InputStream is;
            HttpURLConnection httpconn = (HttpURLConnection) conn;
            if (httpconn.getResponseCode() == 200) {
                is = httpconn.getInputStream();
            } else {
                is = httpconn.getErrorStream();
            }
            in = new BufferedReader(new InputStreamReader(is));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常！" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }

    /**
     * GET请求
     *
     * @param requestUrl 请求地址
     * @return
     */
    public static String get(String requestUrl, String body, String ak_secret, String ak_id) {
        HttpURLConnection connection = null;
        InputStream is = null;
        BufferedReader br = null;
        String result = null;
        try {
            /** 创建远程url连接对象 */
            URL url = new URL(requestUrl);
            /** 通过远程url对象打开一个连接，强制转换为HttpUrlConnection类型 */
            connection = (HttpURLConnection) url.openConnection();
            /** 设置连接方式：GET */
            connection.setRequestMethod("GET");
            /** 设置连接主机服务器超时时间：15000毫秒 */
            connection.setConnectTimeout(15000);
             /** 设置读取远程返回的数据时间：60000毫秒 */
            connection.setReadTimeout(60000);
            /** 设置通用的请求属性 */

            /*
             * http header 参数
             */
            String method = "GET";
            String accept = "application/json";
            String content_type = "application/json;chrset=utf-8";
            String path = url.getFile();
            String date = toGMTString(new Date());
            String host = url.getHost();
            // 1.对body做MD5+BASE64加密
            String bodyMd5 = MD5Base64(body);
            String uuid = UUID.randomUUID().toString();
            String stringToSign = method + "\n" + accept + "\n" + bodyMd5 + "\n" + content_type + "\n" + date + "\n"
                    + "x-acs-signature-method:HMAC-SHA1\n"
                    + "x-acs-signature-nonce:" + uuid + "\n"
                    + "x-acs-version:2019-01-02\n"
                    + path;
            // 2.计算 HMAC-SHA1
            String signature = HMACSha1(stringToSign, ak_secret);
            // 3.得到 authorization header
            String authHeader = "acs " + ak_id + ":" + signature;

            connection.setRequestProperty("Accept", accept);
            connection.setRequestProperty("Content-Type", content_type);
            connection.setRequestProperty("Content-MD5", bodyMd5);
            connection.setRequestProperty("Date", date);
            connection.setRequestProperty("Host", host);
            connection.setRequestProperty("Authorization", authHeader);
            connection.setRequestProperty("x-acs-signature-nonce", uuid);
            connection.setRequestProperty("x-acs-signature-method", "HMAC-SHA1");
            connection.setRequestProperty("x-acs-version", "2019-01-02");  // 版本可选

           // 设置传入参数的格式:请求参数应该是 name1=value1&name2=value2 的形式
//            connection.setRequestProperty("Content-Type", content_type);
/** 发送GET方式请求，使用connet方法建立和远程资源之间的实际连接即可 */
            connection.connect();
            /*-------------------------->*/



/** 获取所有相应头字段 */
//            Map<String, List<String>> map = connection.getHeaderFields();
/** 遍历响应头字段 */
//            for (String key : map.keySet()) {
//                System.out.println(key + "---------->" + map.get(key));
//            }



            /* <-------------------------- */
/** 请求成功：返回码为200 */
            if (connection.getResponseCode() == 200) {
/** 通过connection连接，获取输入流 */
                is = connection.getInputStream();
/** 封装输入流is，并指定字符集 */
                br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
/** 存放数据 */
                StringBuffer sbf = new StringBuffer();
                String line = null;
                while ((line = br.readLine()) != null) {
                    sbf.append(line);
                    sbf.append("\r\n");
                }
                result = sbf.toString();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
/** 关闭资源 */
            try {
                if (null != br) {
                    br.close();
                }
                if (null != is) {
                    is.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
/** 关闭远程连接 */
// 断开连接，最好写上，disconnect是在底层tcp socket链接空闲时才切断。如果正在被其他线程使用就不切断。
// 固定多线程的话，如果不disconnect，链接会增多，直到收发不出信息。写上disconnect后正常一些
            connection.disconnect();
            System.out.println("--------->>> GET request end <<<----------");
        }
        return result;
    }


     public void baidufanyi(){


     }

}
